package castle.defense.project;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;

/**
 * Class defining a projectile that is created by a weapon
 * in order to attack either an enemy or a player's castle.
 * Projectiles have a certain attack damage, radius of effect,
 * and range that correspond to the weapon that created it. 
 * Additionally, the projectile must keep track of the amount of 
 * distance it is traveled, and whether it is an offensive or defensive projectile.
 * 
 * @author KevinJoslyn
 *
 */
public class Projectile extends Moveable {

	private static final int height = 50;
	private static int defaultColor = Color.BLACK;
	public int attackDamage;
	boolean offensive, hit, visible;
	private Paint paint;

	/**
	 * Basic Projectile constructor.
	 * 
	 * @param image			The hash key of this projectile's image.
	 * @param p				The LinearPoint representing this projectile's movement in the game
	 * @param size			The size of this projectile && radius of effect
	 * @param deathSound	The hash key of this projectile's death sound
	 * 
	 * @param ad		The projectile's attack damage (corresponds to
	 * 					the weapon that created the projectile.)
	 * @param offensive 	Enemy projectiles are denoted by a 1, player projectiles are denoted
	 * 						by a 0
	 */
	public Projectile(int image, LinearPoint p, float size, int deathSound,
			int ad, boolean offensive) {

		super(height, image, p, size, deathSound);
		attackDamage = ad;
		this.offensive = offensive;
		paint = new Paint();
		paint.setStyle(Style.FILL_AND_STROKE);
		paint.setColor(defaultColor);
		visible = true;
	}

	/**
	 * Projectile constructor without predefined LinearPoint
	 * 
	 * @param image			The hash key of this projectile's image.
	 * @param x				The projectile's x coordinate (abstract units)
	 * @param y				The projectile's y coordinate (abstract units)
	 * @param speed			The projectile's speed
	 * @param angle			The angle representing the projectile's direction of travel
	 * @param size			The size of this projectile
	 * @param deathSound	The hash key of this projectile's death sound
	 * 
	 * @param ad		The projectile's attack damage (corresponds to
	 * 					the weapon that created the projectile.)
	 * @param r			The projectile's radius of effect (corresponds to
	 * 					the weapon that created the projectile.)
	 * @param offensive 	Enemy projectiles are denoted by a 1, player projectiles are denoted
	 * 						by a 0
	 */
	public Projectile(int image, double x, double y, double speed, double angle,
			float size, int deathSound,	int ad, boolean offensive) {

		this(image,new LinearPoint(x,y,speed,angle),size,deathSound,ad,offensive);
	}


	/**
	 * Basic constructor for a projectile with no art.
	 * @param p LinearPoint for this projectile
	 * @param size Size of the projectile
	 * @param ad Attack Damage
	 * @param offensive Whether or not this projectile is offensive.
	 */
	public Projectile(LinearPoint p, float size, int ad, boolean offensive) {
		this(-1,p,size,-1,ad,offensive);
	}

	public Projectile(double x, double y, double speed, double angle, float size, int ad, boolean offensive) {
		this(new LinearPoint(x,y,speed,angle),size,ad,offensive);
	}

	public Projectile(double x, double y, double speed, double angle, float size, int ad, boolean offensive, boolean draw) {
		this(x,y,speed,angle,size,ad,offensive);
		this.visible = draw;
	}

	/**
	 * Method handling the consequences of a projectile's destruction.
	 * If the projectile has hit an object, its impact() method will be
	 * called and the death sound will be played.
	 */
	public void onDeath() {

	}

	/**
	 * Asks whether the given Projectile object should be destroyed and thereby
	 * removed from the screen.
	 * 
	 * @return true if the projectile is outside of the viewable area, or if the
	 * 		   projectile has exceeded its maximum range, or if the projectile has
	 * 		   hit a target on the screen
	 * @return false if the projectile should continue to be drawn
	 * 
	 * @see Moveable.destroy()
	 */
	public boolean destroy() {
		if(hit || super.destroy()) {
			onDeath();
			return true;
		}
		return false;
	}

	public void setColor(int c) {
		paint.setColor(c);
	}

	public void draw(Canvas c) {
		if(visible) {
			if(image>=0) {
				GraphicsEngine.draw(c, image, p.getScreenX()-size, p.getScreenY()-size);
			} else {
				GraphicsEngine.drawOval(c, p, size, paint);
			}
		}
	}

	public void hit() {
		hit = true;
	}

	public int height() {
		return height;
	}
}
